/*
 * Copyright (C) 2009 M. Hautle.
 * 
 * This file is part of TrackedBean.
 * 
 * TrackedBean is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 * 
 * TrackedBean is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU Lesser General License for more details.
 * 
 * You should have received a copy of the GNU Lesser General License along with TrackedBean. If not, see <http://www.gnu.org/licenses/>.
 */
package ch.trackedbean.validator;

import ch.simpleel.util.*;

/**
 * Context of an currently running validation.
 * 
 * @author M. Hautle
 */
public interface IValidationContext {
    /**
     * Adds error on the specified property.<br>
     * For EL paths see {@link ELHelper}.
     * 
     * @param path The property name or EL path (it will be extended by the current path of the context)
     * @param errors The objects describing the validation error or null if there were none
     * @return True if an error message was added
     */
    boolean addErrors(String path, IErrorDescription... errors);

    /**
     * Adds an general error
     * 
     * @param error The error objects describing the validation error or null if there was none
     * @return True if an error message was added
     */
    boolean addGeneralError(IErrorDescription error);

    /**
     * Call this method if want to step down in an object.
     * 
     * @param elementName The element name
     * @param element The element you want to enter
     * @return True if you can step down, false if the given object is already visited
     */
    boolean stepIntoObject(String elementName, Object element);

    /**
     * Call this method when you came back from an object (so after calling {@link #stepIntoObject(String, Object)} and validating something).<br>
     * If the passed flag is true then the passed error message will be set on the passed element.
     * 
     * @param element The element you leave
     * @param error The object describing the validation error or null if there was none
     */
    void stepOutOfObject(Object element, IErrorDescription error);

    /**
     * Call this method if want to step down in a collection object.
     * 
     * @param index The index of the element in the list
     * @param element The element you want to enter (which is at the given position in the list)
     * @return True if you can step down, false if the given object is already visited
     */
    boolean stepIntoCollectionElement(int index, Object element);

    /**
     * Call this method when you came back from a collection object (so after calling {@link #stepIntoCollectionElement(int, Object)} and validating something).
     */
    void stepOutOfCollectionElement();

    /**
     * Call this method if want to step down in a map object.
     * 
     * @param key The key of the element in map
     * @param element The element you want to enter (which is at the given position in the list)
     * @return True if you can step down, false if the given object is already visited
     */
    boolean stepIntoMapElement(Object key, Object element);

    /**
     * Call this method when you came back from a map object (so after calling {@link #stepIntoMapElement(Object, Object)} and validating something).
     */
    void stepOutOfMapElement();

    /**
     * Returns the value for the given key (previously stored using {@link #putValue(Object, Object)}).
     * 
     * @param <T> The type
     * @param key The key
     * @return The value for the given key or null
     */
    <T> T getValue(Object key);

    /**
     * Stores the given value using the passed key.<br>
     * Stored value can be retrieved using {@link #getValue(Object)}.
     * 
     * @param key The key
     * @param value The value
     * @return The previously value of the specified key
     */
    Object putValue(Object key, Object value);

    /**
     * Returns the result object
     * 
     * @return The result object
     */
    ValidationResult getResult();
}
